<template>
	<div id="picture-upload">
		<input
			ref="fileInput"
			type="file"
			accept="image/jpeg,image/jpg,image/png"
			@change="handleFileSelect"
			style="display: none"
		/>
		<a-button
			@click="triggerFileSelect"
			:loading="loading"
			type="primary"
			size="small"
		>
			<template #icon>
				<UploadOutlined />
			</template>
			{{ loading ? '上传中...' : '选择文件' }}
		</a-button>

		<!-- 图片预览操作区域 -->
		<div class="preview-actions" v-if="currentPictureUrl || pictureUrl">
			<div class="preview-info">
				<CheckCircleOutlined class="success-icon" />
				<span class="success-text">图片已上传</span>
			</div>
			<div class="action-buttons">
				<a-button type="text" size="small" @click="previewImage" class="preview-btn">
					<template #icon>
						<EyeOutlined />
					</template>
					预览
				</a-button>
			</div>
		</div>

		<!-- 自定义图片预览弹窗 -->
		<div v-if="previewVisible" class="custom-image-preview-overlay" @click="previewVisible = false">
			<div class="custom-preview-container" @click.stop>
				<div class="preview-header">
					<span class="preview-title">图片预览</span>
					<button class="close-btn" @click="previewVisible = false">
						<CloseOutlined />
					</button>
				</div>
				<div class="preview-image-container">
					<div class="image-wrapper" @click="toggleFullscreen">
						<img
							:src="currentPictureUrl || pictureUrl"
							alt="预览图片"
							class="preview-image"
							:class="{ 'fullscreen': isFullscreen }"
							@error="onImageError"
						/>
						<div class="image-overlay">
							<div class="overlay-content">
								<EyeOutlined class="fullscreen-icon" />
								<span class="fullscreen-text">{{ isFullscreen ? '退出全屏' : '全屏查看' }}</span>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { UploadOutlined, EyeOutlined, CheckCircleOutlined, CloseOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { uploadPictureByFile } from '@/api/userController'

interface Props {
	pictureUrl?: string
	onSuccess?: (newPictureUrl: string) => void
}

const props = defineProps<Props>()

const loading = ref<boolean>(false)
const previewVisible = ref<boolean>(false) // 预览Modal显示状态
const currentPictureUrl = ref<string>('') // 当前上传的图片URL
const fileInput = ref<HTMLInputElement>() // 文件输入框引用
const isFullscreen = ref<boolean>(false) // 全屏状态

// 触发文件选择
const triggerFileSelect = () => {
	fileInput.value?.click()
}

// 处理文件选择
const handleFileSelect = async (event: Event) => {
	const target = event.target as HTMLInputElement
	const file = target.files?.[0]
	if (!file) return

	// 文件验证
	if (!beforeUpload(file)) {
		return
	}

	// 上传文件
	loading.value = true
	try {
		const res: any = await uploadPictureByFile({}, file)
		if (res.data.code === 0 && res.data.data) {
			message.success('图片上传成功')
			currentPictureUrl.value = res.data.data
			props.onSuccess?.(res.data.data)
		} else {
			message.error('图片上传失败，' + res.data.message)
		}
	} catch (error: any) {
		console.error('图片上传失败', error)
		message.error('图片上传失败，' + error.message)
	} finally {
		loading.value = false
		// 清空文件输入框
		if (target) target.value = ''
	}
}

// 图片上传前的校验
const beforeUpload = (file: File) => {
	const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
	if (!isJpgOrPng) {
		message.error('不支持上传该格式的图片，推荐 jpg 或 png')
		return false
	}
	const isLt2M = file.size / 1024 / 1024 < 2
	if (!isLt2M) {
		message.error('不能上传超过 2MB 的图片!')
		return false
	}
	return true
}

/**
 * 处理图片预览
 */
const previewImage = () => {
	if (currentPictureUrl.value || props.pictureUrl) {
		previewVisible.value = true
	}
}

/**
 * 处理图片加载失败
 */
const onImageError = () => {
	message.error('图片加载失败，请检查图片是否有效')
}

/**
 * 切换全屏状态
 */
const toggleFullscreen = () => {
	isFullscreen.value = !isFullscreen.value
}
</script>
<style scoped lang="scss">
#picture-upload {
	margin-bottom: 16px;

	:deep(.ant-upload) {
		width: 100% !important;
		height: 100% !important;
		min-height: 152px;
		min-width: 152px;

		img {
			max-width: 100%;
			max-height: 480px;
		}

		.ant-upload-select-picture-card i {
			font-size: 32px;
			color: #999;
		}
		.ant-upload-select-picture-card .ant-upload-text {
			margin-top: 8px;
			color: #666;
		}
	}

	// 预览操作区域样式
	.preview-actions {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 8px 12px;
		background: #f6ffed;
		border: 1px solid #b7eb8f;
		border-radius: 6px;
		margin-top: 8px;
		transition: all 0.3s ease;

		.preview-info {
			display: flex;
			align-items: center;
			gap: 6px;

			.success-icon {
				color: #52c41a;
				font-size: 14px;
			}

			.success-text {
				color: #389e0d;
				font-size: 12px;
				font-weight: 500;
			}
		}

		.action-buttons {
			display: flex;
			gap: 4px;

			.preview-btn {
				color: #1890ff;
				font-size: 12px;
				padding: 0 8px;
				height: 24px;

				&:hover {
					background: rgba(24, 144, 255, 0.1);
					color: #096dd9;
				}
			}
		}
	}

	// 响应式：移动端
	@media (max-width: 768px) {
		.preview-actions {
			flex-direction: column;
			gap: 8px;
			align-items: stretch;

			.preview-info {
				justify-content: center;
			}

			.action-buttons {
				justify-content: center;
				gap: 12px;
			}
		}
	}
}

// 自定义图片预览弹窗样式
.custom-image-preview-overlay {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.6);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 1000;
	backdrop-filter: blur(4px);
	animation: fadeIn 0.2s ease-out;
}

.custom-preview-container {
	background: white;
	border-radius: 8px;
	box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
	overflow: hidden;
	max-width: 90vw;
	max-height: 90vh;
	animation: slideIn 0.3s ease-out;
}

.preview-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 16px 20px;
	border-bottom: 1px solid #f0f0f0;
	background: #fafafa;

	.preview-title {
		font-size: 16px;
		font-weight: 500;
		color: #333;
	}

	.close-btn {
		width: 32px;
		height: 32px;
		border: none;
		background: transparent;
		border-radius: 4px;
		cursor: pointer;
		display: flex;
		align-items: center;
		justify-content: center;
		color: #666;
		transition: all 0.2s;

		&:hover {
			background: #f0f0f0;
			color: #333;
		}
	}
}

.preview-image-container {
	padding: 20px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: #fff;

	.image-wrapper {
		position: relative;
		cursor: pointer;
		border-radius: 8px;
		overflow: hidden;
		transition: all 0.3s ease;

		&:hover {
			.image-overlay {
				opacity: 1;
			}
		}

		.preview-image {
			max-width: 300px;
			max-height: 300px;
			width: auto;
			height: auto;
			object-fit: contain;
			border-radius: 8px;
			box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
			transition: all 0.3s ease;

			&.fullscreen {
				max-width: 90vw;
				max-height: 90vh;
				width: auto;
				height: auto;
				cursor: zoom-out;
			}
		}

		.image-overlay {
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			bottom: 0;
			background: rgba(0, 0, 0, 0.5);
			display: flex;
			align-items: center;
			justify-content: center;
			opacity: 0;
			transition: opacity 0.3s ease;
			border-radius: 8px;

			.overlay-content {
				display: flex;
				flex-direction: column;
				align-items: center;
				gap: 8px;
				color: white;
				text-align: center;

				.fullscreen-icon {
					font-size: 24px;
				}

				.fullscreen-text {
					font-size: 14px;
					font-weight: 500;
				}
			}
		}
	}
}

@keyframes fadeIn {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}

@keyframes slideIn {
	from {
		transform: scale(0.9) translateY(-20px);
		opacity: 0;
	}
	to {
		transform: scale(1) translateY(0);
		opacity: 1;
	}
}
</style>
